package com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.crm;

import com.alibaba.acm.shaded.com.google.common.collect.Maps;
import com.alibaba.cirtus.ots.application.adapter.ability.model.enums.MnSAPStatus;
import com.alibaba.cirtus.ots.application.adapter.ability.model.response.CallApiRecordResponse;
import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.citrus.ots.common.util.SapAndCrmFieldDealUtils;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.middleware.cache.runtime.service.EpochCacheService;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.crpricecenter.model.dto.SyncActivityTitleExtDataRequest;
import com.epoch.app.crpricecenter.model.dto.SyncActivityTitleExtDataResponse;
import com.epoch.app.crpricecenter.service.CrPriceCenterService;
import com.epoch.app.otsapplicationadaptersdk.crm.MnCrmCommResponse;
import com.epoch.app.otsapplicationadaptersdk.crm.MnCrmCommSDO;
import com.epoch.app.otsapplicationadaptersdk.crm.MnCrmIf005Request;
import com.epoch.app.otsapplicationadaptersdk.crm.MnCrmIf005SDO;
import com.epoch.app.otsapplicationadaptersdk.crmv2.mncrmif005v2.service.MnCrmIf005V2Service;
import com.epoch.app.otsapplicationadaptersdk.model.dto.MessageHeaderPassiveSDO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author hanguo
 * @date 2021/10/12
 * @Description crm请求平台同步促销活动更改（活动量及活动金额）
 */
@Component
public class MnCrmIf005V2ServiceImpl implements MnCrmIf005V2Service {
    private static final Log log = Log.getLogger(MnCrmIf005V2ServiceImpl.class);

    @Resource
    private CrPriceCenterService crPriceCenterService;
    @Resource
    private EpochCacheService epochCacheService;

    private static final String MESSAGE_ID = "messageId";

    private static final String DATA_SOURCE = "dataSource";

    private static final String SPLIT = "\\.";
    private static final String KEY = "MnCrmIf005";
    //设置sap过期时间为
    private static final Long CRM_TIMESTAMP_CACHE_EXPIRE = 60 * 60 * 24 * 100L;
    private static final String CRM_SENDER = "MNCRM";

    @ProcessInvoker(remark = "MnCrmIf005V2Service", errorCode = "OTS-02-007-00-16-999", printLog = true)
    @Override
    public MnCrmCommResponse externalSyncUpdatePromotionActivity(MnCrmIf005Request mnCrmIf005Request) {
        MnCrmCommResponse mnCrmCommResponse = new MnCrmCommResponse();
        mnCrmCommResponse.setMessageId(mnCrmIf005Request.getMessageHeader().getMessageId());
        mnCrmCommResponse.setInterfacePath(mnCrmIf005Request.getMessageHeader().getInterfacePath());
        MnCrmCommSDO mnCrmCommSDO = new MnCrmCommSDO();

        //数据来源记录
        MessageHeaderPassiveSDO messageHeader = mnCrmIf005Request.getMessageHeader();
        Map<String,String> features = Maps.newHashMap();
        if(Objects.nonNull(messageHeader)){
            //数据头信息id
            features.put(MESSAGE_ID,messageHeader.getMessageId());
            //数据来源 sap或者excel等
            features.put(DATA_SOURCE, messageHeader.getSender());
        }

        CallApiRecordResponse callApiRecordResponse = new CallApiRecordResponse();

        if (Objects.nonNull(mnCrmIf005Request.getData())) {
            //检查时间戳 如果时间戳小于之前执行的,则不处理
            String checkMessageTimeMessage = checkMessageTime(mnCrmIf005Request);
            if (StringUtils.isNotBlank(checkMessageTimeMessage)){
                log.info("MnCrmIf005ServiceImpl_externalSyncUpdatePromotionActivity_messageTimeNotLatest:{}",JSONObject.toJSONString(mnCrmIf005Request));
                mnCrmCommSDO.setResultType(MnSAPStatus.ERROR.getCode());
                mnCrmCommSDO.setResultMessage(checkMessageTimeMessage);
                mnCrmCommResponse.setData(mnCrmCommSDO);
                return mnCrmCommResponse;
            }
            MnCrmIf005SDO data = mnCrmIf005Request.getData();
            SyncActivityTitleExtDataRequest syncActivityTitleExtDataRequest = new SyncActivityTitleExtDataRequest();
            syncActivityTitleExtDataRequest.setActivityNoteId(data.getActivityNoteId());
            syncActivityTitleExtDataRequest.setApplyItemQuantity(SapAndCrmFieldDealUtils.toLong(data.getApplyItemQuantity()));
            String applyFee = data.getApplyFee();
            if (StringUtils.isNotBlank(applyFee)) {
                BigDecimal multiply = new BigDecimal(applyFee.trim()).multiply(new BigDecimal(100));
                syncActivityTitleExtDataRequest.setApplyFee(multiply.setScale(2, RoundingMode.HALF_DOWN).longValue());
            }
            //syncActivityTitleExtDataRequest.setApplyFee(SapAndCrmFieldDealUtils.toLong(data.getApplyFee()));
            syncActivityTitleExtDataRequest.setSalesUnit(data.getSalesUnit());
            syncActivityTitleExtDataRequest.setCurrency(data.getCurrency());
            syncActivityTitleExtDataRequest.setFeatures(JSONObject.toJSONString(features));
            syncActivityTitleExtDataRequest.setSender(mnCrmIf005Request.getMessageHeader().getSender());
            SyncActivityTitleExtDataResponse syncActivityTitleExtDataResponse = crPriceCenterService.syncActivityTitleExtData(syncActivityTitleExtDataRequest);
            log.info("促销活动修改金额和数量 result = {}", JSONObject.toJSONString(syncActivityTitleExtDataResponse));
            if (!syncActivityTitleExtDataResponse.getSuccess()) {
                mnCrmCommSDO.setResultType(MnSAPStatus.ERROR.getCode());
                mnCrmCommSDO.setResultMessage(syncActivityTitleExtDataResponse.getMessage());
            }
            callApiRecordResponse.setMessage(syncActivityTitleExtDataResponse.getMessage());
            callApiRecordResponse.setOperateResult(callApiRecordResponse.getOperateResult());
            callApiRecordResponse.setTableName("ofs_activity_title_ext");
            callApiRecordResponse.setRequestBody(JSONObject.toJSONString(syncActivityTitleExtDataRequest));
        }else{
            mnCrmCommSDO.setResultType(MnSAPStatus.ERROR.getCode());
            mnCrmCommSDO.setResultMessage("请传数据!");
        }
        //如果没有执行出错的记录
        if (StringUtils.isBlank(mnCrmCommSDO.getResultType())&&StringUtils.isBlank(mnCrmCommSDO.getResultMessage())) {
            mnCrmCommSDO.setResultType(MnSAPStatus.SUCCESS.getCode());
            mnCrmCommSDO.setResultMessage("同步成功");
        }
        //设置时间戳缓存
        if (MnSAPStatus.SUCCESS.getCode().equals(mnCrmCommSDO.getResultType()) &&
                CRM_SENDER.equals(Optional.ofNullable(mnCrmIf005Request)
                        .map(MnCrmIf005Request::getMessageHeader)
                        .map(MessageHeaderPassiveSDO::getSender).orElse(null))){
            MnCrmIf005SDO sdo = mnCrmIf005Request.getData();
            epochCacheService.put(BcOtsConstants.REDIS_CACHE_CODE(),KEY + sdo.getActivityNoteId(),sdo.getMessageTime(),
                    CRM_TIMESTAMP_CACHE_EXPIRE, TimeUnit.SECONDS);
        }
        log.info("MnCrmIf005ServiceImpl_externalSyncUpdatePromotionActivity => 执行结束修改结果 = {}",JSONObject.toJSONString(callApiRecordResponse));

        mnCrmCommResponse.setData(mnCrmCommSDO);

        return mnCrmCommResponse;
    }

    /**
     * 比较时间戳和缓存的时间戳
     * @param request
     * @return
     */
    private String checkMessageTime(MnCrmIf005Request request){
        MnCrmIf005SDO sdo = request.getData();
        String sender = Optional.ofNullable(request).map(MnCrmIf005Request::getMessageHeader).map(MessageHeaderPassiveSDO::getSender).orElse(null);
        //tpm没有携带时间戳 所以如果没有时间戳则认为是tpm的
        if (CRM_SENDER.equals(sender)){
            if (StringUtils.isBlank(sdo.getMessageTime())){
                return "时间戳messageTime不能为空";
            }
        }else {
            return null;
        }
        String[] messageTimeArray = sdo.getMessageTime().split(SPLIT);
        if (messageTimeArray == null || messageTimeArray.length !=2 ||
                StringUtils.isAnyBlank(messageTimeArray[0],messageTimeArray[1])){
            return "时间戳messageTime格式错误";
        }

        String messageTime = sdo.getMessageTime();
        String activityNoteId = sdo.getActivityNoteId();
        String cacheMessageTime = epochCacheService.get(BcOtsConstants.REDIS_CACHE_CODE(), KEY + activityNoteId);
        if (earlierThanOrEqualTo(messageTime,cacheMessageTime)) {
            return "当前修改时间早于上一次 不允许更新";
        }
        return null;
    }

    private boolean earlierThanOrEqualTo(String messageTime,String cacheMessageTime){
        //缓存时间为空时,允许更新
        if (StringUtils.isBlank(cacheMessageTime)){
            return false;
        }
        String[] array = messageTime.split(SPLIT);
        String[] cacheArray = cacheMessageTime.split(SPLIT);
        if (Long.parseLong(array[0]) > Long.parseLong(cacheArray[0])){
            return false;
        }else if (Long.parseLong(array[0]) == Long.parseLong(cacheArray[0])){
            return Long.parseLong(array[1]) <= Long.parseLong(cacheArray[1]);
        }
        return true;
    }
}
